ELK LFI CVE-2018-17246

Kibana中的本地文件包含允许攻击者运行本地JavaScript文件

1
2
3
PoC:
GET /api/console/api_server?sense_version=%40%40SENSE_VERSION&apis=../../../../../../../../../../../etc/passwd
GET /api/console/api_server?sense_version=%40%40SENSE_VERSION&apis=es_6.0

介绍

随着组织涌向Elastic的开源Elasticsearch来搜索和分析大量数据,许多人正在利用Kibana插件来可视化,探索和理解这些信息。作为Elastic Stack的核心组件,Kibana可作为产品或服务提供,并与各种系统,产品,网站和企业中的其他Elastic Stack产品配合使用。

本文将探讨由CyberArk实验室发现的Kibana中一个严重的严重本地文件包含(LFI)漏洞。根据OWASP基金会的说法,“LFI是通过利用应用程序中实施的易受攻击的包含程序来包含已经存在于服务器上的文件的过程。”通常,这种攻击方法用于敏感信息泄露,但是在某些情况下,正如您将在此处阅读的那样,它使攻击者能够执行服务器上存在的代码。

在发现此漏洞后,CyberArk Labs在负责的披露流程后于2018年10月向Elastic发出警告。分配给CVE-2018-17246的漏洞随后由Elastic修复。

更多关于Kibana和控制台

与其他Elastic Stack产品类似,Kibana是一个开源的Node.js服务器,呈现为Web UI。Kibana与Elasticsearch合作搜索和分析大型复杂数据流,使其更容易通过数据可视化和图形理解。Kibana具有多种功能,每种功能都有不同的插件:默认情况下,每个Kibana都安装并激活了核心插件,还有需要激活的插件,还有一些需要不仅仅是免费的基本许可证。

控制台是基本插件,它位于“开发工具”部分下的基本Kibana。此插件提供了一个UI,用于在不使用cURL的情况下与Elasticsearch REST API交互,使用户能够编写JSON查询并通过Kibana的Web界面获取响应。控制台还具有历史记录功能,可维护Elasticsearch成功执行的最近500个请求的列表。控制台也容易受到本地文件包含攻击。

让我们找一个易受攻击的函数

本地Web代理是可用于测试Web应用程序的最有效的灰盒渗透测试工具之一,因为它允许研究人员查看从客户端到服务器的通信。在下面的示例中,我们的团队使用PortSwigger的Burp Suite来映射潜在的攻击面。交换了大量信息,但一个特定的HTTP请求引起了我们的注意:

img图1 - 从客户端发送到Kibana服务器的有趣请求

这个请求很有意思,因为它引用了控制台服务器的API。也许我们可以操作一些API函数来做有趣的事情,也许我们可以创建自己的API函数,无论如何这个“es_6_0”参数是什么?它看起来像某种东西。如果是,那意味着有一个旧版本,也许我们可以降级某些东西并利用修补的漏洞?

有两种方法可以解决这个问题:一种方法是读取代码(毕竟它是开源代码),另一种方法是开始发送所有类型的输入并查看我们得到的响应。在这个特定场景中,我们选择了第二种方法,因为我们正在进行灰盒测试(Burp Suite中的入侵者功能在这种情况下非常有用)。

我们开始测试并观察到许多输入在我们达到超时之前没有响应。这是不正常的,所以我们检查了日志。一项具体要求立即引发了一个红旗:

img图2-记录的错误表示请求容易受到路径遍历的影响

此参数是一种基本的路径遍历攻击技术,许多攻击者使用该技术来识别易受本地文件包含攻击并查看敏感数据的区域。文件/ etc / passwd几乎总是存在于Linux系统上,并且是检查通用本地文件包含的主要目标。

因此,我们知道我们可以使用路径遍历来访问系统中的某些本地文件,而不会向攻击者返回任何响应,并且错误中的数据也是部分的。要完全了解正在发生的事情并且看看我们是否可以利用此漏洞,最好阅读具体的代码。通常,在灰盒测试中读取代码超出范围,但在这种情况下,我们设法将代码减少到特定区域,因此它是可管理的。日志中另一个异常的堆栈跟踪帮助我们确定代码的确切位置:

img图3 - 记录的错误揭示了易受攻击的代码

###

了解Bug

以下是记录的错误中的文件内容,可以让我们了解这里发生的事情:

img图4 - server.js

哦! 看看我们在同一目录中找到了什么:

img图5 - api_server文件夹的内容

所以,现在我们知道API参数是什么 - 我们将要求的JavaScript文件的名称并调用asJson函数(图4中的第27-28行)。我们可以看到没有对名为name的变量的内容进行验证,因此,用户可以输入他/她想要的任何内容。

函数asJson是在api.js文件中编写的Api类的一部分:

img图6 - api.js

在es_6_0.js中有一个这个类的导出实例:

img图7 - es_6_0.js

让我们总结一下迄今为止我们所知道的内容。此函数的正常流程是获取导出Api类实例并调用函数asJson的JavaScript文件的名称。没有输入验证,因此我们可以将JavaScript文件的名称更改为我们想要的任何内容。在这种情况下,使用路径遍历技术,我们可以选择Kibana服务器上的任何文件。

所以这就是 - 漏洞,一种加载服务器上已有的JavaScript代码的方法。但是我们可以用它来做什么,因为如果没有函数asJson,我们会收到一条错误消息而没有别的?

要求(“了解要求”)

require函数是在Node.js中加载模块的方式。我们将探索require函数来说明只需加载模块即可完成的任务。对于那些有兴趣深入挖掘的人,我们在参考部分中包含了几个链接。

在Node.js中,模块可以是“核心模块”,这意味着它们被编译成Node.js二进制文件。模块也可以是包含名为“package.json”,“index.js”或“index.node”的文件的文件或文件夹.require函数的第一个操作是识别它作为参数接收的模块类型和解决他的位置。如果参数与核心模块匹配,则require函数知道从哪里加载它。或者,如果参数以“/”,“./”或“../”开头,则函数知道该模块将是文件或文件夹(它取决于参数将指示我们的位置)。最后一个选项是这是一个位于名为“node_modules”的文件夹中的模块(文件或文件夹),该文件夹可以位于当前模块的父目录和根目录之间的目录之一中。在我们的例子中,require函数的参数以“./”开头,因此它必须是文件或文件夹。使用路径遍历,我们可以导航到服务器上的每个文件或文件夹。

在require函数解析模块的位置之后,它接受模块的代码并用函数包装器包装它,如下所示:

img图8 - 模块包装器结构(来源:https://nodejs.org/api/modules.html)

此函数称为模块包装器。执行模块包装器并返回模块导出的对象(使用module.exports对象及其快捷方式)。模块必须从模块代码外部导出需要访问的所有内容,因为模块封装器将所有内容限定为模块。换句话说,除非导出模块代码,否则模块代码中的每个对象都是私有的。

执行模块包装器后,将缓存模块的导出对象。这意味着如果require函数将使用相同的参数调用,它将不会创建另一个模块包装器并执行它,而是从缓存中返回相同的导出对象。

在我们的例子中,我们可以访问服务器磁盘上的每个模块,它将被执行一次,并且只执行一次,并且执行将被限制,因此正在运行的代码无法访问它的每个对象。因此,我们需要找到一个Node.js模块,该模块包含一个不需要导出的代码,可以在不将其作为函数调用或从中创建新对象的情况下运行。

好!好!停止漫步并告诉我你得到了什么!

搜索Node.js脚本的第一个地方是Kibana本身的文件。基于上面的解释,很明显运行Node.js应用程序需要大量文件,如果这些文件属于Kibana,它们更有可能影响Kibana操作。我们的搜索产生了两个模块,可以关闭Kibana进程并导致拒绝服务:

第一个模块是“{KIBANA_PATH} /src/docs/docs_repo.js”:

img图9 - docs / cli.js

要加载第二个模块,require可以引用三个路径(模块关闭进程,但如果这不起作用,这可以帮助我们覆盖缓存机制):

  • {KIBANA_PATH} / SRC / cli_plugin
  • {} KIBANA_PATH /src/cli_plugin/index.js
  • {} KIBANA_PATH /src/cli_plugin/cli.js

它们最终都运行了具有此代码的最后一个路径:

img图10 - cli_plugin / cli.js的一部分

在一长串模块之后,这也执行process.exit。我们来测试一下:

img图11 - 通过强制服务器要求cli_plugin / cli.js的DOS

以下是日志的结果:

img图12 - cli_plugin / cli.js的结果

通常,Kibana与其他应用程序一起部署(例如,将其日志写入Elasticsearch和Kibana的应用程序允许用户查看它们)。在这些情况下,我们有时可以使用应用程序上传一个JavaScript文件,例如Node.js反向shell:

img图13 - Node.js反向shell代码(来源:https://github.com/appsecco/vulnerable-apps/tree/master/node-reverse-shell)

路径遍历技术允许我们访问Kibana获得许可的服务器上的每个位置。像这样:

img图14 - 使服务器需要反向shell脚本

日志:

img图15-在日志中加载反向shell

我们得到:

img图16 - 反向壳体pwnage!

###

摘要

本地文件包含是一个已知的漏洞,有时 - 并且错误地 - 被视为旧闻。现实情况是,虽然软件开发人员和架构师可能没有考虑LFI,但攻击者正在越来越多地重新审视这种技术并寻找流行的Web应用程序(如Kibana)中存在的漏洞。

这篇文章说明了Elastic的Kibana中一个关键的LFI漏洞,它使攻击者能够在服务器本身上运行本地代码。我们演示了具有文件上载功能的服务器上的其他服务如何使攻击者能够上传代码 - 无需首先运行服务器磁盘上的代码并允许远程代码执行功能。

披露时间表

  • 2018年10月23日:LFI漏洞向Elastic报告
  • 2018年10月23日:Elastic回复说他们将审核该报告
  • 2018年10月28日:Elastic对报告进行了验证,并表示他们将准备安全更新。
  • 2018年10月29日:CyberArk研究员注意到对Kibana GitHub所做的更改表明Elastic尝试解决此问题。这些变化是在10月23日进行的。
  • 2018年11月6日:Elastic发布了针对此问题的修复程序并分配了漏洞CVE-2018-17246

参考

转自:https://www.cyberark.com/threat-research-blog/execute-this-i-know-you-have-it/

-------------本文结束感谢您的阅读-------------